package com.daxia.bumall.web.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.daxia.bumall.basemodel.CoreUser;
import com.daxia.bumall.common.ProductSortType;
import com.daxia.bumall.dao.BrandDAO;
import com.daxia.bumall.dto.BrandDTO;
import com.daxia.bumall.dto.BrowseRecordDTO;
import com.daxia.bumall.dto.DesignDTO;
import com.daxia.bumall.dto.FactoryInfoDTO;
import com.daxia.bumall.dto.ProductCategoryDTO;
import com.daxia.bumall.dto.ProductCategoryTagDTO;
import com.daxia.bumall.dto.ProductDTO;
import com.daxia.bumall.dto.ProductPropertiesDTO;
import com.daxia.bumall.dto.SpecShow;
import com.daxia.bumall.model.Brand;
import com.daxia.bumall.model.Specification;
import com.daxia.bumall.model.User;
import com.daxia.bumall.support.Page;
import com.daxia.bumall.util.SpringSecurityUtils;
import com.daxia.bumall.util.ValidationUtils;

@Controller
@RequestMapping("product")
public class ProductController extends BaseController {
	private static Logger logger = Logger.getLogger(ProductController.class);
	
	@Autowired
	private BrandDAO brandDAO;
	
    @RequestMapping(value = "/detail")
    public String detail(Long id,Long specificationId,Map<String, Object> map) {  
    	ProductDTO p = productService.load(id);
    	p.setDefaultSpec(specificationId);
    	map.put("p", p);
    	
    	//用户进行浏览，将对应的浏览记录存入到库里
    	BrowseRecordDTO record = new BrowseRecordDTO();
    	record.setSpecification(p.getDefaultSpec());
    	CoreUser coreUser = SpringSecurityUtils.getCurrentUser();
    	
    	//ValidationUtils.assertTrue(coreUser != null, "您还没有登陆，请登录后使用购物车功能!");
    	if (coreUser != null) {
	    	User user = new User();
	    	user.setId(coreUser.getId());
	    	record.setUser(user);
	    	record.setBrowseTime(new Date());
	    	browseRecordService.create(record);
    	}
    	
    	FactoryInfoDTO factoryInfoDTO = factoryInfoService.findFactoryByUserId(p.getUser().getId());
    	map.put("factoryInfo", factoryInfoDTO);
    	Page page = new Page();
    	page.setPageSize(50);
    	ProductDTO queryBrand = new ProductDTO();
    	queryBrand.setBrand(p.getBrand());
    	ProductDTO queryCategory = new ProductDTO();
    	queryCategory.setProductCategory(p.getProductCategory());
    	
    	ProductDTO recProduct = new ProductDTO();
    	recProduct.getFilterIds().add(p.getId());   //过滤商品本身
    	
    	queryBrand.getFilterIds().add(p.getId());     //过滤掉商品本身
    	queryCategory.getFilterIds().add(p.getId());
    	
    	Page recPage = new Page();
    	recPage.setPageSize(10);
    	
    	map.put("recProducts", productService.recProducts(recProduct, recPage));
    	map.put("sameBrandProducts", productService.find(queryBrand, page));
    	map.put("sameCategoryProducts", productService.find(queryCategory, page));
    	Long userId = p.getUser().getId();
    	FactoryInfoDTO factory = factoryInfoService.findFactoryByUserId(userId);
    	map.put("f", factory);
    	
    	List<ProductDTO> p1List = productService.findRandom(1);
    	if (CollectionUtils.isNotEmpty(p1List)) {
    		map.put("p1", p1List.get(0));
    	}
    	List<ProductDTO> p2List = productService.findRandom(1);
    	if (CollectionUtils.isNotEmpty(p2List)) {
    		map.put("p2", p2List.get(0));
    	}
    	if(StringUtils.isNotBlank(p.getImages())) {
    		map.put("images", p.getImages().split(","));
    	} else {
    		map.put("images",new String[]{});
    	}
    	//显示规格，进行了合并显示
    	map.put("specs", getSpecInfo(p));
    	//推荐方案
    	List<DesignDTO> designs = designService.find(4);
    	map.put("designs", designs);
    	
    	/**
    	 * 产品类目图片，此处先说明，页面上要进行对应的图片切换，图片包括：产品图片+各类类目图片，根据
    	 * 类目切换来显示不同类目的对应图片，产品的图片还是不变
    	 */
    	map.put("categories", productCategoryService.findAllRoot());
        return "product/product_detail";
    }
    
    public List<List<SpecShow>> getSpecInfo(ProductDTO product) {   //前台展现的规格需要合并,要做各种操作，所以需要使用代码合并,只是初始化,颜色是需要完全列出来，大小的规格是需要判定显示的
    	List<Specification> specifications = product.getSpecifications();
    	List<List<SpecShow>> specs = new Vector<List<SpecShow>>(2);
    	List<SpecShow> colorSpec = new Vector<SpecShow>();   //颜色分类规格
    	List<SpecShow> sizeSpec = new Vector<SpecShow>();    //大小规格
    	Specification defaultSpec = product.getDefaultSpec();   //得到默认的选中规格
    	for(Specification theSpec:specifications) {
    		String theColor = theSpec.getSpec1();
    		String theSize = theSpec.getSpec2();
    		boolean ifHas = false;
    		if(isListNotBlank(colorSpec)) {   //首先去看是否已经有了该颜色属性
    			for(SpecShow cSpec:colorSpec) { 
    				if(cSpec.getShowName().equals(theColor)) {
    					cSpec.getIds().add(theSpec.getId());
    					ifHas = true;
    					break;
    				} 
    			}
    		}
    		if(!ifHas) {  //如果没有找到，添加
    			SpecShow newSpec = createNewSpecShow(theColor);
    			newSpec.getIds().add(theSpec.getId());
    			if(theColor.equals(defaultSpec.getSpec1())) {
    				newSpec.setSpecDefault(true);
    			}
    			colorSpec.add(newSpec);
    		}
    		boolean sizeIfHas = false;
    		if(isListNotBlank(sizeSpec)) {   //首先去看是否已经有了该颜色属性
    			for(SpecShow cSpec:sizeSpec) {
    				if(cSpec.getShowName().equals(theSize)) {
    					cSpec.getIds().add(theSpec.getId());
    					sizeIfHas = true;
    					break;
    				}
    			}
    		}
    		if(!sizeIfHas) {  //如果没有找到，添加
    			SpecShow newSpec = createNewSpecShow(theSize);
    			newSpec.getIds().add(theSpec.getId());
    			if(theSize.equals(defaultSpec.getSpec2())) {
    				newSpec.setSpecDefault(true);
    			}
    			sizeSpec.add(newSpec);
    		}
    	}
    	specs.add(colorSpec);
    	specs.add(sizeSpec);
    	return specs;
    }
    
    public SpecShow createNewSpecShow(String name) {
    	SpecShow spec = new SpecShow();
    	spec.setShowName(name);
    	return spec;
    }
    
    public boolean isListNotBlank(List list) {
    	return list != null && list.size() > 0;
    }
    
    public List<Long> getIdsFromStr(String idstr) {
    	List<Long> idList = new Vector<Long>();
    	if(StringUtils.isNotBlank(idstr)) {
    		String[] ids = idstr.split(";");
    		for(String theId:ids) {
    			if(StringUtils.isNotBlank(theId)) {
    				idList.add(Long.parseLong(theId));
    			}
    		}
    	}
    	return idList;
    }

    @RequestMapping(value = "/list")
    public String list(String filters, Long id, ProductDTO dto,String brandInfo, Map<String, Object> map, Page page,HttpServletRequest request,
    		Boolean liveDirect) throws Exception { //brands:选中的品牌ids
    	if (liveDirect == null) {
    		liveDirect = false;
    	}
    	map.put("liveDirect", liveDirect);
    	if (liveDirect) {
    		map.put("menuType", 3);
    	}
    	page.setPageSize(20);
    	List<Long> brandIds = getIdsFromStr(brandInfo);
    	dto.setBrandIds(brandIds);
    	map.put("dto", dto);
    	
    	if (logger.isDebugEnabled()) {
    		logger.debug("filters before: " + filters);
    	}
    	if (filters == null) {
    		filters = "";
    	}
    	String[] arr = filters.split(";");
    	Map<String, String> filterMap = new HashMap<String, String>();
    	List<ProductPropertiesDTO> properties = new Vector<ProductPropertiesDTO>();
    	for (String string : arr) {
    		String[] arr2 = string.split(":");
    		if (arr2.length == 2) {
    			filterMap.put(arr2[0], arr2[1]);
    			ProductPropertiesDTO theProp = new ProductPropertiesDTO();
        		theProp.setName(arr2[0]);
        		theProp.setValue(arr2[1]);
        		properties.add(theProp);
    		}
		}
    	if (logger.isDebugEnabled()) {
			logger.debug("filterMap: " + filterMap);
		}
    	map.put("filterMap",filterMap);
    	
    	if(dto != null && dto.getName() != null ) {
    		request.getSession().setAttribute("search", dto.getName());
    		//2017-01-09 由于涉及到新的搜索形式，如：产品分类+颜色，产品分类+风格 产品分类+材质，需要从分类信息和属性信息里联合查询,分离可能出现的情况，如：床  实木 白色
    		String searchInfo = dto.getName();
    		String[] words = searchInfo.split("\\s+");
    		if(words.length > 1) {
    			dto.setCategoryName(words[0]);   //第一个是分类信息
    			//List<String> propName = new Vector<String>();
    			for(int i = 1;i < words.length;i ++ ) {
    				ProductPropertiesDTO aProperty = new ProductPropertiesDTO();
    				aProperty.setValue(words[i]);
    				properties.add(aProperty);
    			}
    			//dto.setPropertyNames(propName);
    		}
    	}
    	
    	//filters = WebParamUtils.getUTF8Param(filters);
    	//if (logger.isDebugEnabled()) {
    		//logger.debug("filters after: " + filters);
    	//}
    	
    	if(dto.getSortType() != null) { 
    		map.put("sortType",dto.getSortType());
    	} 
    	map.put("sortTypes",ProductSortType.values());
    	//List<ProductDTO> products = productService.find(dto, page);

    	if (liveDirect) {
    		List<BrandDTO> liveDirectBrands = brandService.find(8);
    		map.put("brands", liveDirectBrands);
    		List<Long> ids = new ArrayList<Long>();
    		for (BrandDTO brandDTO : liveDirectBrands) {
    			ids.add(brandDTO.getId());
			}
    		dto.setLiveDirectBrandIds(ids);
    	}
    	List<ProductDTO> products = productService.getProductByProperties(properties, dto,page); 
    	map.put("products", products);
    	if (liveDirect) {
    	} else {
    		List<Brand> brands = productService.getDistinctBrands(properties, dto);
    		map.put("brands", brands);
    	}
    	//此处更改，directed BY:xiaoxiong 因为要涉及到价格等的查询，所以，最终的查询结果应该是规格的结果，再由规格去关联产品
    	//List<SpecificationDTO> specs = productService.getSpecificationByProperties(properties, dto, page);
    	//map.put("specs", specs);
    	map.put("styles", houseStyleService.findAll());
    	map.put("categories", productCategoryService.findAllRoot());
    	if (dto.getProductCategory() != null && dto.getProductCategory().getId() != null) {
    		map.put("currentCategory", productCategoryService.load(dto.getProductCategory().getId()));
    	}
    	//map.put("brands", brandService.findAll());
    	map.put("page", page);
    	
    	if(dto.getProductCategory() != null && dto.getProductCategory().getId() != null) {
    		List<ProductCategoryTagDTO> allTags = new ArrayList<ProductCategoryTagDTO>();
        	ProductCategoryDTO pc = productCategoryService.load(dto.getProductCategory().getId());
        	allTags.addAll(productCategoryTagService.findByProductCategory(pc.getId()));
        	if (pc.getParentCategory() != null) {
        		allTags.addAll(productCategoryTagService.findByProductCategory(pc.getParentCategory().getId()));
        		if (pc.getParentCategory().getParentCategory() != null) {
        			allTags.addAll(productCategoryTagService.findByProductCategory(pc.getParentCategory().getParentCategory().getId()));
        		}
        	}
        	map.put("tags", processTags(allTags, pc));
    	}
        return "product/product_list";
    }

	private List<ProductCategoryTagDTO> processTags(List<ProductCategoryTagDTO> allTags, ProductCategoryDTO pc) {
		if (CollectionUtils.isEmpty(allTags)) {
			return allTags;
		}

		// 去重
		Set<String> nameSet = new HashSet<String>();
		for (int i = allTags.size() - 1; i >= 0; i--) {
			if (!nameSet.add(allTags.get(i).getName())) {
				allTags.remove(i);
				continue;
			}
		}
		
		for (ProductCategoryTagDTO t : allTags) {
			if ("品牌".equals(t.getName())) {
				List<BrandDTO> allBrands = new ArrayList<BrandDTO>();
				
				allBrands.addAll(brandService.toDTOs(brandDAO.findAllBrandsByProductCategory(pc.getId())));
				t.setBrands(allBrands);
			}
		}
		
		// 最后再筛选一次
		for (int i = allTags.size() - 1; i >= 0; i--) {
			if ("品牌".equals(allTags.get(i).getName()) || "价格".equals(allTags.get(i).getName())) {
				continue;
			}
			if (StringUtils.isBlank(allTags.get(i).getValues())) {
				allTags.remove(i);
				continue;
			}
		}
		return allTags;
	}
}	
